
class Formattable {
 public:
  Formattable (const string& table_name);

  bool readFormat ();
  bool saveFormat ();
  bool saveNumPages ();

  bool setColumnFormat (const string& name, int type = 0, int len = 0);
  bool setColumnName (const string& name, const string& new_name);

  bool addColumn (const string& name, int type, int len);
  bool removeColumn (const string& name);
  
  int getColumnIndex (const string &name); /* returns -1 when column is not found */
  string& getColumnName (int index);
  int getColumnType (int index);
  int getColumnLen (int index);

  int getColumnCount ();
  int getRowLength   ();

  bool isVarCol (int index);

  map<int, VarCol> varCols; /* This belongs to live format containers but needs to be public */

 private:
  void beginFormatModification ();  /* Makes modifiable (un-committed) copies of format containers */

 protected:
  bool formatModified;
  bool numPagesModified; /* whether or not new pages were added */

  unsigned int numPages;
  vector<TablePage> pages;

  /* Live format */
  map<string, int> colName;
  vector<string>   colNameIndex;
  vector<int>      colLen;
  vector<int>      colType;
  int              rowLength;
  int              numColumns;

  vector<bool> removedColumns; /* Carries indeces of columns that got removed */

  /* Un-committed format */
  map<string, int> colNameMod;
  vector<string>   colNameIndexMod;
  vector<int>      colLenMod;
  vector<int>      colTypeMod;
  map<int, VarCol> varColsMod;
  int              rowLengthMod;
  int              numColumnsMod;

  Mutex formatModMutex;
  Mutex pageAddMutex; /* ensures that only one thread is currently adding a new page */
  Cond  pageAddCond;

  string formatName; /* These are to be set by Table */
  string tableName;
};

